﻿using System;
using System.Windows.Forms;
using System.Diagnostics;
using MSOutlook = Microsoft.Office.Interop.Outlook;
using MSOffice = Microsoft.Office.Core;

namespace Microsoft.Sample.Outlook.Utility.Ribbon
{
    public class OutlookInspector
    {
        #region Instance Variables

        private MSOutlook.Inspector m_Window;                         // wrapped window object
        private MSOutlook.ContactItem m_Contact;                      // wrapped ContactItem
        private MSOffice.CommandBarButton ctlCBarButton;              // CommandBarButton
        private MSOffice.CommandBarComboBox ctlCBarCombo;             // CommandBarCombo
        private MSOffice.CommandBar cbWidget;                         // CommandBar
        private string m_RibbonColor;
        private string m_CommandBarColor;

		#endregion

		#region Events

		public event EventHandler Close;
        public event EventHandler<InvalidateEventArgs> InvalidateControl;

		#endregion

		#region Constructor

		/// <summary>
		/// Create a new instance of the tracking class for an inspector 
		/// </summary>
        /// <param name="inspector">The new inspector window to monitor</param>
        ///<remarks></remarks>
		public OutlookInspector(MSOutlook.Inspector inspector)
		{
			m_Window = inspector;
            m_Contact = (MSOutlook.ContactItem)inspector.CurrentItem;
            m_RibbonColor = "Red";//Properties.Resources.Color_Red;
            m_CommandBarColor = "Red";//Properties.Resources.Color_Red;
			// Hookup events
            ((MSOutlook.InspectorEvents_Event)inspector).Close += new MSOutlook.InspectorEvents_CloseEventHandler(OutlookWindow_Close);
            m_Contact.Open += new MSOutlook.ItemEvents_10_OpenEventHandler(m_Contact_Open);
            ((MSOutlook.ItemEvents_10_Event)m_Contact).Close += new MSOutlook.ItemEvents_10_CloseEventHandler(m_Contact_Close);
            m_Contact.PropertyChange += new MSOutlook.ItemEvents_10_PropertyChangeEventHandler(m_Contact_PropertyChange);
		}
		#endregion

        #region Item-level Events
        // Remove Color Widgets custom CommandBar
        private void m_Contact_Close(ref bool CancelDefault)
        {
            RemoveColorWidgets();
        }

        // Create Color Widgets custom CommandBar
        private void m_Contact_Open(ref bool CancelDefault)
        {
            CreateColorWidgets();
        }

        // This event procedure listens for Address changes on the item
        // If all addresses are empty, then set visible state of cbWidgets to false.
        // Also calls RaiseInvalidateControl to invalidate ColorWidgetsGroup.
        // Invalidataing a control causes RibbonX callbacks to fire again for the specific control.
        // To improve performance, RibbonX best practice is to call InvalidateControl 
        // rather than Invalidate which invalidates all controls on all Ribbons.
        // ColorWidgetsGroup_GetVisible handles visibility of ColorWidgetsGroup
        private void m_Contact_PropertyChange(string Name)
        {
            switch (Name)
            {
                case "BusinessAddress":
                    if (String.IsNullOrEmpty(m_Contact.BusinessAddress) &
                        String.IsNullOrEmpty(m_Contact.HomeAddress) &
                        String.IsNullOrEmpty(m_Contact.OtherAddress))
                    {
                        cbWidget.Visible = false;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    else
                    {
                        cbWidget.Visible = true;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    break;
                case "HomeAddress":
                    if (String.IsNullOrEmpty(m_Contact.BusinessAddress) &
                        String.IsNullOrEmpty(m_Contact.HomeAddress) &
                        String.IsNullOrEmpty(m_Contact.OtherAddress))
                    {
                        cbWidget.Visible = false;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    else
                    {
                        cbWidget.Visible = true;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    break;
                case "OtherAddress":
                    if (String.IsNullOrEmpty(m_Contact.BusinessAddress) &
                        String.IsNullOrEmpty(m_Contact.HomeAddress) &
                        String.IsNullOrEmpty(m_Contact.OtherAddress))
                    {
                        cbWidget.Visible = false;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    else
                    {
                        cbWidget.Visible = true;
                        RaiseInvalidateControl("ColorWidgetsGroup");
                    }
                    break;
            }
        }
        #endregion

        #region CommandBar Code
        //Test to ensure that a CommandBar exists
        private bool CommandBarExists(string CommandBarName)
        {
            MSOffice.CommandBar oCB;
            try
            {
                oCB = m_Contact.GetInspector.CommandBars[CommandBarName];
                return true;
            }
            catch
            {
                return false;
            }         
        }

        //Remove Color Widgets CommandBar
        private void RemoveColorWidgets()
        {
            try
            {
                if(CommandBarExists("Color Widget"))//Properties.Resources.CommandBarName
                {
                    cbWidget.Delete();
                }
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        //Create Color Widgets CommandBar
        private void CreateColorWidgets()
        {
            try
            {
                if (!CommandBarExists("Color Widget"))//Properties.Resources.CommandBarName
                {
                    cbWidget = m_Contact.GetInspector.CommandBars.Add("Color Widgets", MSOffice.MsoBarPosition.msoBarTop, Type.Missing, true);
                    //CommandBarButton
                    ctlCBarButton = (MSOffice.CommandBarButton)cbWidget.Controls.Add(MSOffice.MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    ctlCBarButton.Caption = "Color";
                    ctlCBarButton.FaceId = 2167;
                    ctlCBarButton.Tag = "OutlookRibbonXAddinCS.ColorButton";
                    ctlCBarButton.Parameter = "OutlookRibbonXAddinCS.ColorButton";
                    ctlCBarButton.Style = MSOffice.MsoButtonStyle.msoButtonIconAndCaption;
                    ctlCBarButton.Visible = true;
                    ctlCBarButton.TooltipText = "Display selected color";
                    //CommandBarComboBox
                    ctlCBarCombo = (MSOffice.CommandBarComboBox)cbWidget.Controls.Add(MSOffice.MsoControlType.msoControlComboBox, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    ctlCBarCombo.Tag = "OutlookRibbonXAddinCS.ColorCombo";
                    ctlCBarCombo.Parameter = "OutlookRibbonXAddinCS.ColorCombo";
                    ctlCBarCombo.AddItem("Red", Type.Missing);
                    ctlCBarCombo.AddItem("Green", Type.Missing);
                    ctlCBarCombo.AddItem("Blue", Type.Missing);
                    ctlCBarCombo.ListIndex = 1;
                }
                else
                {
                    cbWidget = m_Contact.GetInspector.CommandBars["Color Widgets"];
                }
                //Make the command bar visible only if an address exists
                if (String.IsNullOrEmpty(m_Contact.BusinessAddress) & String.IsNullOrEmpty(m_Contact.HomeAddress) & String.IsNullOrEmpty(m_Contact.OtherAddress))
                {
                    cbWidget.Visible = false;
                }
                else
                {
                    cbWidget.Visible = true;
                }
                //Hookup button and combo box event handlers
                ctlCBarButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(ctlCBarButton_Click);
                ctlCBarCombo.Change += new Microsoft.Office.Core._CommandBarComboBoxEvents_ChangeEventHandler(ctlCBarCombo_Change);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        void ctlCBarButton_Click(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if(m_Window == m_Contact.Application.ActiveInspector())
            {
                MessageBox.Show("The current selected color is" + m_CommandBarColor, "Color Widgets",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
        }

        void ctlCBarCombo_Change(Microsoft.Office.Core.CommandBarComboBox Ctrl)
        {
            m_CommandBarColor = Ctrl.Text;
        }
        #endregion

        #region Event Handlers


		/// <summary>
		/// Event Handler for the inspector close event.
		/// </summary>
		private void OutlookWindow_Close()
		{
            // Unhook events from the window
            m_Contact.Open -= new Microsoft.Office.Interop.Outlook.ItemEvents_10_OpenEventHandler(m_Contact_Open);
            ((MSOutlook.ItemEvents_10_Event)m_Contact).Close -= new Microsoft.Office.Interop.Outlook.ItemEvents_10_CloseEventHandler(m_Contact_Close);
            m_Contact.PropertyChange -= new Microsoft.Office.Interop.Outlook.ItemEvents_10_PropertyChangeEventHandler(m_Contact_PropertyChange);
            ctlCBarButton.Click -= new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(ctlCBarButton_Click);
            ctlCBarCombo.Change -= new Microsoft.Office.Core._CommandBarComboBoxEvents_ChangeEventHandler(ctlCBarCombo_Change);
            ((MSOutlook.InspectorEvents_Event)m_Window).Close -= new Microsoft.Office.Interop.Outlook.InspectorEvents_CloseEventHandler(OutlookWindow_Close);


            // Raise the OutlookInspector close event
			if (Close != null)
			{
				Close(this, EventArgs.Empty);
			}

            m_Window = null;
            m_Contact = null;
		}
		#endregion

        #region Methods
        private void RaiseInvalidateControl(string controlID)
        {
            if (InvalidateControl != null)
                InvalidateControl(this, new InvalidateEventArgs(controlID));

        }
        #endregion

        #region Properties

        /// <summary>
		/// The actual Outlook inspector window wrapped by this instance
		/// </summary>
        public MSOutlook.Inspector Window
		{
			get { return m_Window; }
		}

        /// <summary>
        /// The RibbonColor for this inspector window.
        /// </summary>
        public string RibbonColor
        {
            get { return m_RibbonColor; }
            set { m_RibbonColor = value; }
        }

        /// <summary>
        /// The CurrentItem for this inspector window.
        /// </summary>
        public MSOutlook.ContactItem CurrentItem
        {
            get { return m_Contact; }
        }
		#endregion

        #region Helper Class
        public class InvalidateEventArgs : EventArgs
        {
            private string m_ControlID;

            public InvalidateEventArgs(string controlID)
            {
                m_ControlID = controlID;
            }

            public string ControlID
            {
                get { return m_ControlID; }
            }
        }
        #endregion
    }
}
